<script setup lang="ts">
import {
  useSwipe,
  useScroll,
  useIntersectionObserver,
  useIntervalFn
} from "@vueuse/core";
const props = defineProps({
  autoPlay: {
    type: Boolean,
    default: false
  },
  loop: {
    type: Boolean,
    default: false
  }
});
const target = ref();
const currIdx = ref(0);
const slots = useSlots();
const items = slots.default?.() ?? [];
const len = ref(0);
let pause: any = null,
  resume: any = null,
  stopSwipe: any = null,
  stopObserver: any = null;
let obsOpt = {
  root: target.value,
  threshold: 0.8
};
onUpdated(() => {
  len.value = target.value.querySelectorAll(".swiper-item").length;
  if (len.value == 0) return;
  ({ stop: stopSwipe } = useSwipe(target, {
    threshold: 50,
    onSwipeStart(e) {
      if (props.autoPlay && pause) {
        pause();
      }
    },
    onSwipeEnd(e, dir) {
      if (props.autoPlay && resume) {
        resume();
      }
    }
  }));
  target.value
    .querySelectorAll(".swiper-item")
    .forEach((el: any, idx: number, arr: Element[]) => {
      ({ stop: stopObserver } = useIntersectionObserver(
        el,
        ([{ isIntersecting }], observerElement) => {
          if (isIntersecting) {
            currIdx.value = idx;
          }
        },
        obsOpt
      ));
    });
  if (props.loop) {
    let items: Element[] = Array.from(
      target.value.querySelectorAll(".swiper-item")
    );
    let first = items[items.length - 1].cloneNode(true);
    let last = items[0].cloneNode(true);
    target.value.insertBefore(first, items[0]);
    target.value.appendChild(last);
    target.value.scroll({
      left: target.value.clientWidth,
      behavior: "instant"
    });
    useIntersectionObserver(
      ref(target.value.firstElementChild),
      ([{ isIntersecting }], observerElement) => {
        if (isIntersecting) {
          target.value.scroll({
            left: target.value.clientWidth * len.value
            //behavior:'instant'
          });
        }
      },
      obsOpt
    );
    useIntersectionObserver(
      ref(target.value.lastElementChild),
      ([{ isIntersecting }], observerElement) => {
        if (isIntersecting) {
          target.value.scroll({
            left: target.value.clientWidth
            //behavior:'instant'
          });
        }
      },
      obsOpt
    );
  }
  if (props.autoPlay) {
    ({ pause, resume } = useIntervalFn(() => {
      if (currIdx.value == len.value - 1) {
        target.value.scrollLeft = 0;
      } else {
        target.value.scrollLeft += target.value.clientWidth;
      }
    }, 2000));
  }
});
onBeforeUnmount(() => {
  if (stopSwipe) stopSwipe();
  if (stopObserver) stopObserver();
  if (pause) pause();
});
</script>

<template>
  <div
    class="swiper-container"
    w:pos="relative"
    w:w="max-screen"
    w:h="max-screen"
  >
    <div
      ref="target"
      class="swiper-wrapper scroll-smooth"
      w:flex="~ nowrap"
      w:overflow="scroll"
      w:w="full"
      w:h="full"
    >
      <slot />
    </div>
    <div
      class="swiper-indicator"
      w:pos="absolute bottom-4"
      w:flex="~ nowrap"
      w:w="full"
      w:align="items-center"
      w:justify="center"
    >
      <template v-for="(item, idx) in len" :key="idx">
        <div class="indicator-item dot" :class="{ active: currIdx == idx }" />
      </template>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.swiper-container {
  width: 750px;
  //height: 200px;
}
.swiper-wrapper {
  scroll-snap-type: both mandatory;
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE 10+ */
  &::-webkit-scrollbar {
    display: none; /* Chrome Safari */
  }
}
.swiper-indicator {
  .dot {
    width: 14px;
    height: 14px;
    margin: 0 6px;
    border-radius: 20px;
    transition: all 0.5s;
    background-color: rgba(0, 0, 0, 0.3);
    &.active {
      background-color: rgba(255, 255, 255, 0.8);
    }
  }
}
</style>
